package UserInterface;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;


import DataReading.Alarm;
import DataReading.AlarmList;
import DataReading.LoadSystem;
import DataReading.Tools;
import DataReading.Vessel;
import DataReading.VesselList;

public class tableUI extends JFrame {
	
	public JTextField timerField;
	private JPanel checkBoxPanel; // checkbox panel
	private JPanel buttonPanel; // button panel
	private JPanel sliderPanel; // slider panel
	private JPanel tablePanel; // table panel
	public JButton startPauseButton;
	public JButton tableBackButton; // back button
	private JButton gridFromTable; // button that links to grid from the table
	public JCheckBox swimmer;
	public JCheckBox speedBoat;
	public JCheckBox fishingBoat;
	public JCheckBox cargoVessel;
	public JCheckBox passengerVessel;
	private JButton dualView;
	private JTable table = null;
	private JScrollPane scrollPane;
	private JTable alarmTable = null;
	private JScrollPane alarmScrollPane;
	private JLabel timeStep;
	private JLabel vessels;
	private JComboBox sortSelection;
	private JComboBox sortAscDsc;
	public static JSlider slider;
	final int WINDOW_WIDTH = 800;
	final int WINDOW_HEIGHT = 800;
	public gridUI grid;
	public initUI init;
	LoadSystem system;
	//Timer timer = new Timer(initUI.currentSliderValue, new TimerListener());
	String[] columnNames = {"Vessel ID","Type", "XPosition", "YPosition", "Speed", "Course", "Distance", "UpdateTime" };
	String[] alarmColumnNames = {"Vessel-1 ID","1-Type", "Vessel-2 ID", "2-Type", "Distance", "Alarm Type" };
	String[] sortOptions = {"Vessel ID", "Type", "XPosition", "YPosition", "Speed", "Course", "Distance", "UpdateTime" };
	String[] sortAscDscOptions = {"Ascending Order", "Descending Order"};
	
	
	public tableUI(initUI initial, LoadSystem system){
		
		setTitle("Table"); // sets window title
		setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // sets window size
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // close when red X is clicked
		this.system = system;
		buildCheckBoxPanel();
		buildButtonPanel();
		buildSliderPanel();
		buildTablePanel(system);
		add(checkBoxPanel, BorderLayout.WEST);
		add(buttonPanel, BorderLayout.NORTH);
		add(sliderPanel, BorderLayout.SOUTH);
		add(tablePanel, BorderLayout.CENTER);
		
		init = initial;
	}
	
	private void buildButtonPanel(){
		
		startPauseButton = new JButton("Start"); // creates start Button
		startPauseButton.setBackground(Color.GREEN);
		startPauseButton.addActionListener(new ButtonListener());
		tableBackButton = new JButton("Back to Menu"); // creates back to menu button
		tableBackButton.addActionListener(new ButtonListener()); //adds listener to back to menu button
		gridFromTable = new JButton("Grid"); // creates table button
		gridFromTable.addActionListener(new ButtonListener()); // adds listener to table button
		dualView = new JButton("Dual-View");
		dualView.addActionListener(new ButtonListener());
		buttonPanel = new JPanel(); // creates panel
		buttonPanel.setBackground(Color.BLACK);
		buttonPanel.add(startPauseButton); // adds start/pause button
		buttonPanel.add(tableBackButton); // adds back to menu button
		buttonPanel.add(gridFromTable); // adds grid button		
		buttonPanel.add(dualView); // adds dual view button
	}
	
	private void buildCheckBoxPanel(){ // NOT DONE ACTION LISTENERS OR SCROLL BAR
		
		checkBoxPanel = new JPanel();
		checkBoxPanel.setLayout(new GridLayout(initUI.shipTypes.length + 2, 1));
		checkBoxPanel.setBackground(Color.BLACK);
		checkBoxPanel.setBorder(BorderFactory.createLineBorder(Color.ORANGE, 4));
		vessels = new JLabel("Vessel Filtering:");
		vessels.setBackground(Color.BLACK);
		vessels.setForeground(Color.ORANGE);
		timerField = new JTextField(); 
		timerField.setText("Time Elapsed: 0.0s");
		timerField.setEditable(false);
		//timerField.setFont(new Font("Arial", Font.BOLD, 16));
		timerField.setForeground(Color.GREEN);
		timerField.setBackground(Color.BLACK);
		timerField.setBorder(BorderFactory.createLineBorder(Color.ORANGE, 1));
		checkBoxPanel.add(timerField);
		checkBoxPanel.add(vessels);
		swimmer = new JCheckBox(initUI.shipTypes[0], true);
		swimmer.addActionListener(new CheckBoxListener());
		speedBoat = new JCheckBox(initUI.shipTypes[1], true);
		speedBoat.addActionListener(new CheckBoxListener());
		fishingBoat = new JCheckBox(initUI.shipTypes[2], true);
		fishingBoat.addActionListener(new CheckBoxListener());
		cargoVessel = new JCheckBox(initUI.shipTypes[3], true);
		cargoVessel.addActionListener(new CheckBoxListener());
		passengerVessel = new JCheckBox(initUI.shipTypes[4], true);
		passengerVessel.addActionListener(new CheckBoxListener());
		swimmer.setBackground(Color.BLACK);
		swimmer.setForeground(Color.ORANGE);
		speedBoat.setBackground(Color.BLACK);
		speedBoat.setForeground(Color.ORANGE);
		fishingBoat.setBackground(Color.BLACK);
		fishingBoat.setForeground(Color.ORANGE);
		cargoVessel.setBackground(Color.BLACK);
		cargoVessel.setForeground(Color.ORANGE);
		passengerVessel.setBackground(Color.BLACK);
		passengerVessel.setForeground(Color.ORANGE);
		checkBoxPanel.add(swimmer);
		checkBoxPanel.add(speedBoat);
		checkBoxPanel.add(fishingBoat);
		checkBoxPanel.add(cargoVessel);
		checkBoxPanel.add(passengerVessel);
	
	}
	
	private void buildSliderPanel(){ // NOT DONE ACTION LISTENER
		
		sliderPanel = new JPanel();
		sliderPanel.setBackground(Color.BLACK);
		timeStep = new JLabel("TIMESTEP (in milliseconds): ");
		timeStep.setForeground(Color.ORANGE);
		slider = new JSlider(JSlider.HORIZONTAL, 500, 5000, init.system.getInfo().getTimeStep() * 1000);
		slider.setPreferredSize(new Dimension(300,90));
		slider.setMajorTickSpacing(500);
		slider.setMinorTickSpacing(100);
		slider.setPaintTicks(true);
		slider.setPaintLabels(true);
		slider.setBackground(Color.BLACK);
		slider.setForeground(Color.ORANGE);
		slider.addChangeListener(new SliderListener());

		sliderPanel.add(timeStep);
		sliderPanel.add(slider);
		
		
		
	}
	
	private void buildTablePanel(LoadSystem x) {
		tablePanel = new JPanel();
		tablePanel.setBackground(Color.BLACK);
		tablePanel.setLayout(new FlowLayout());
				
		table = new JTable(createModel(getTableData(x), columnNames));
        table.setPreferredScrollableViewportSize(new Dimension(620,400));
		table.setBackground(Color.BLACK);
		table.setForeground(Color.YELLOW);
		centerTable(table);
		scrollPane = new JScrollPane(table);
		scrollPane.getViewport().setBackground(Color.BLACK);
		JLabel tableHeader  =  new JLabel("Vessels");
		tableHeader.setForeground(Color.ORANGE);
		tablePanel.add(tableHeader);
		tablePanel.add(scrollPane);
		
		alarmTable = new JTable(createModel(getAlarmTableData(x), alarmColumnNames));
        alarmTable.setPreferredScrollableViewportSize(new Dimension(620,80));
		alarmTable.setBackground(Color.BLACK);
		alarmTable.setForeground(Color.YELLOW);
		centerTable(alarmTable);
		alarmScrollPane = new JScrollPane(alarmTable);
		alarmScrollPane.getViewport().setBackground(Color.BLACK);
		JLabel alarmTableHeader  =  new JLabel("Alarms");
		alarmTableHeader.setForeground(Color.ORANGE);
		tablePanel.add(alarmTableHeader);
		tablePanel.add(alarmScrollPane);
		
		sortSelection = new JComboBox<String>(sortOptions);
		sortSelection.setSelectedIndex(0);
		sortSelection.addActionListener(new ComboBoxListener());
		JLabel sortText = new JLabel("Sort Vessels By: ");
		sortText.setForeground(Color.ORANGE);
		sortAscDsc = new JComboBox<String>(sortAscDscOptions);
		sortAscDsc.setSelectedIndex(0);
		sortAscDsc.addActionListener(new ComboBoxListener());
		JLabel sortAscDscText = new JLabel(" in ");
		sortAscDscText.setForeground(Color.ORANGE);
		tablePanel.add(sortText);
		tablePanel.add(sortSelection);
		tablePanel.add(sortAscDscText);
		tablePanel.add(sortAscDsc);
				
	}
	
	private TableModel createModel(Object[][] x, String[] y) {
		TableModel model = new DefaultTableModel(x, y) {
            public Class getColumnClass(int column) {
                Class returnValue;
                if ((column >= 0) && (column < getColumnCount())) {
                    returnValue = getValueAt(0, column).getClass();
                }
                else {
                    returnValue = Object.class;
                }
                return returnValue;
            }
            public boolean isCellEditable(int row, int col) { return false; }
        };
        return model;
	}
	
	private boolean checkTypeID(int ID) {
		switch (ID) {
		case 1: return swimmer.isSelected();
		case 2: return speedBoat.isSelected();
		case 3: return fishingBoat.isSelected();
		case 4: return cargoVessel.isSelected();
		case 5: return passengerVessel.isSelected();
		default: return true;
		}
	}
	private void centerTable(JTable myTable) {
		for (int i = 0; i < myTable.getModel().getRowCount(); i++) {
			   for (int j = 0; j < myTable.getModel().getColumnCount(); j++) {
			      DefaultTableCellRenderer renderer =
			         (DefaultTableCellRenderer)myTable.getCellRenderer(i, j);
			      renderer.setHorizontalAlignment(JTextField.CENTER);
			   } // End for(j)
			} // End for(i)

	}
	
	public void updateTable() {
        table.setModel(createModel(getTableData(system), columnNames));
        centerTable(table);
        alarmTable.setModel(createModel(getAlarmTableData(system), alarmColumnNames));
        centerTable(alarmTable);
	}
	
	private Object[][] getTableData(LoadSystem x) {
		VesselList currentVessels = x.getCurrentVessels();
		VesselList filteredVessels = new VesselList();
		for (int i = 0; i < currentVessels.getPointer(); i++) {
			Vessel v = currentVessels.getVesselAtIndex(i);
			if (v != null && checkTypeID(v.getType())) {
				filteredVessels.add(v);
			}
		}
		
		Object[][] data = new Object[filteredVessels.getPointer()][8];
		for (int i = 0; i < filteredVessels.getPointer(); i++) {
			Vessel v = filteredVessels.getVesselAtIndex(i);
			if (v != null) {
				data[i][0] = v.getID();
				data[i][1] = v.getTypeName();
				data[i][2] = v.getXPosition();
				data[i][3] = v.getYPosition();
				data[i][4] = v.getSpeed();
				data[i][5] = v.getCourse();
				data[i][6] = v.getDistance();
				data[i][7] = v.getUpdateTime();
			}
		}
		
		return data;
	}
	
	private Object[][] getAlarmTableData(LoadSystem x) {
		AlarmList alarmList = x.getAlarms();
		AlarmList filteredAlarms = new AlarmList();
		for (int i = 0; i < alarmList.getPointer(); i++) {
			Alarm a = alarmList.getAlarmAtIndex(i);
			if (a != null && checkTypeID(a.getVesselX().getType()) && checkTypeID(a.getVesselY().getType())) {
				filteredAlarms.add(a);
			}
		}
		
		Object[][] data = new Object[filteredAlarms.getPointer()][6];
		for (int i = 0; i < filteredAlarms.getPointer(); i++) {
			Alarm a = filteredAlarms.getAlarmAtIndex(i);
			if (a != null) {
				data[i][0] = a.getVesselX().getID();
				data[i][1] = a.getVesselX().getTypeName();
				data[i][2] = a.getVesselY().getID();
				data[i][3] = a.getVesselY().getTypeName();
				data[i][4] = a.getDistance();
				data[i][5] = a.getAlarmName();
			}
		}
		
		return data;
	}
	
	
	private class ButtonListener implements ActionListener{
		
		public void actionPerformed(ActionEvent e){
			
			if (e.getSource() == startPauseButton){
				if (startPauseButton.getText() == "Start") {
					startPauseButton.setText("Pause");
					startPauseButton.setBackground(Color.RED);
					grid.startPauseButton.setText("Pause");
					grid.startPauseButton.setBackground(Color.RED);
					init.timer.setInitialDelay(slider.getValue());
					init.timer.start(); // starts data
					init.secondTimer.start();
				}
				else{
					startPauseButton.setText("Start");
					startPauseButton.setBackground(Color.GREEN);
					grid.startPauseButton.setText("Start");
					grid.startPauseButton.setBackground(Color.GREEN);
					init.timer.stop(); // stops data
					init.secondTimer.stop();
				}
			}
			else if (e.getSource() == tableBackButton){ // if back button was pressed
				setVisible(false); // remove table visibility
				init.setVisible(true); // make initial UI visible
			}
			else if(e.getSource() == gridFromTable){ // if grid button was pressed
				
				setVisible(false); // remove table visibility
				grid.setVisible(true); // make grid visible
			} 
			else if(e.getSource() == dualView){
				
				grid.setVisible(true);
			}
		}
	}
	
	private class  ComboBoxListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == sortSelection) { system.setSortKey(sortSelection.getSelectedIndex());	}
			else if (e.getSource() == sortAscDsc) {	system.setOrderKey(sortAscDsc.getSelectedIndex());	}
		}
		
	}
	
	private class CheckBoxListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			
			if (initUI.optionSelected.equals("Administrator")){
				
				if (e.getSource() == swimmer) grid.swimmer.setSelected(swimmer.isSelected());
				else if (e.getSource() == speedBoat) grid.speedBoat.setSelected(speedBoat.isSelected());
				else if (e.getSource() == fishingBoat) 	grid.fishingBoat.setSelected(fishingBoat.isSelected());
				else if (e.getSource() == cargoVessel)  grid.cargoVessel.setSelected(cargoVessel.isSelected());
				else if (e.getSource() == passengerVessel) grid.passengerVessel.setSelected(passengerVessel.isSelected());
			}
			else{
				if (e.getSource() == swimmer) swimmer.setSelected(true);
				else if (e.getSource() == speedBoat) speedBoat.setSelected(true);
				else if (e.getSource() == fishingBoat) fishingBoat.setSelected(true);
				else if (e.getSource() == cargoVessel) cargoVessel.setSelected(true);
				else if (e.getSource() == passengerVessel) passengerVessel.setSelected(true);
				
				JOptionPane.showMessageDialog(null, "Please sign in as admin to have filtering privileges", "Guest Account", JOptionPane.ERROR_MESSAGE);
			}
		}
	}
	
	private class SliderListener implements ChangeListener{
			
			public void stateChanged(ChangeEvent e){
				initUI.currentSliderValue = slider.getValue();
				gridUI.slider.setValue(slider.getValue());
				init.timer.setDelay(slider.getValue()); // sets timer delay to new slider value
			}
	}
	
}

